/*
 * Copyright (c) 2020 hebeiyiliuba.com
 * All rights reserved.
 *
 */
package org.jeecg.modules.wlhy.report;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.ImageUtil;
import org.jeecg.common.util.LngLonUtil;
import org.jeecg.modules.third.amap.dto.GpsDTO;
import org.jeecg.modules.third.amap.dto.MapDirectionDTO;
import org.jeecg.modules.third.amap.service.AmapService;
import org.jeecg.modules.third.jg.report.freight.information.dto.shippingnote.AlctShippingNoteVO;
import org.jeecg.modules.third.oapi.alct56.constant.enums.CargoTypeEnum;
import org.jeecg.modules.third.oapi.alct56.dto.AlctApiBaseResDTO;
import org.jeecg.modules.third.oapi.alct56.dto.req.image.ShippingImageDTO;
import org.jeecg.modules.third.oapi.alct56.dto.req.shippingnote.*;
import org.jeecg.modules.third.oapi.alct56.dto.req.vehicle.VehicleDTO;
import org.jeecg.modules.third.oapi.alct56.service.AppAlct56Service;
import org.jeecg.modules.third.oapi.alct56.service.OapiAlct56Service;
import org.jeecg.modules.third.openapi.WaybillRouteService;
import org.jeecg.modules.wlhy.bill.entity.HyShippingNoteBill;
import org.jeecg.modules.wlhy.bill.service.IHyBillService;
import org.jeecg.modules.wlhy.bill.service.IHyShippingNoteBillService;
import org.jeecg.modules.wlhy.customer.entity.HyCustomer;
import org.jeecg.modules.wlhy.customer.service.IHyCustomerService;
import org.jeecg.modules.wlhy.hydriver.entity.HyDriver;
import org.jeecg.modules.wlhy.hydriver.service.IHyDriverService;
import org.jeecg.modules.wlhy.hyvehicle.entity.HyVehicle;
import org.jeecg.modules.wlhy.hyvehicle.service.IHyVehicleService;
import org.jeecg.modules.wlhy.order.entity.HyOrder;
import org.jeecg.modules.wlhy.order.service.IHyOrderService;
import org.jeecg.modules.wlhy.setting.service.IHySettingService;
import org.jeecg.modules.wlhy.shipping.dto.LnTaxShippingNoteDTO;
import org.jeecg.modules.wlhy.shipping.entity.HyShippingLntaxReport;
import org.jeecg.modules.wlhy.shipping.entity.HyShippingNote;
import org.jeecg.modules.wlhy.shipping.entity.PointDataListVO;
import org.jeecg.modules.wlhy.shipping.entity.WaybillRouteVO;
import org.jeecg.modules.wlhy.shipping.service.IHyShippingLntaxReportService;
import org.jeecg.modules.wlhy.shipping.service.IHyShippingNoteService;
import org.jeecg.modules.wlhy.utils.HyCfgUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/**
 * 陆交开放平台
 *
 * @author duanlikao
 * @created 2022/3/23
 */
@Service
@Slf4j
public class ShippingNoteApiAlct56Service {

    /**
     * 陆交开放平台
     */
    @Autowired
    private OapiAlct56Service oapiAlct56Service;

    @Autowired
    private AppAlct56Service appAlct56Service;

    @Autowired
    private IHyShippingLntaxReportService hyShippingLntaxReportService;

    @Autowired
    private IHyShippingNoteService hyShippingNoteService;

    @Autowired
    private IHyBillService hyBillService;

    @Autowired
    private IHyVehicleService vehicleService;

    @Autowired
    private IHyOrderService orderService;

    @Autowired
    private IHyDriverService driverService;

    @Autowired
    private IHyShippingNoteBillService hyShippingNoteBillService;

    @Autowired
    private IHyCustomerService customerService;

    @Autowired
    private WaybillRouteService waybillRouteService ;

    @Autowired
    private AmapService amapService;

    @Autowired
    private IHySettingService settingService;

    @Value(value = "${jeecg.path.upload}")
    private String uploadpath;

    @Value(value = "${jeecg.path.bank}")
    private String bankPath;


    /**
     * 陆交开放平台 创建运单
     *
     * @param hyShippingNote
     * @return
     */

    public Result createShippingNote(HyShippingNote hyShippingNote) {
        if (!hyShippingNote.getAlctIdentification().equals("1")) {
            throw new JeecgBootException("该运单不属于辽宁税务运单");
        }

        AlctApiBaseResDTO r = oapiAlct56Service.getAlctShippingNote(hyShippingNote.getShippingNoteNumber());
        if (r.getCode().equals("0")) {
            return Result.error("税务运单已存在，无需重复上传");
        }

        HyOrder hyOrder = orderService.getById(hyShippingNote.getOrderId());
        if (hyOrder == null) {
            throw new JeecgBootException("该运单货源信息不能为空");
        }

        HyVehicle hyVehicle = vehicleService.getById(hyShippingNote.getVehicleId());
        if (hyVehicle == null) {
            throw new JeecgBootException("该运单车辆信息不能为空");
        }
        HyDriver hyDriver = driverService.getById(hyShippingNote.getDriverId());
        if (hyDriver == null) {
            throw new JeecgBootException("该运单司机信息不能为空");
        }

        HyCustomer hyCustomer = customerService.getById(hyShippingNote.getCustomerId());
        if (hyCustomer == null) {
            throw new JeecgBootException("该运单货主信息不能为空");
        }

        HyShippingLntaxReport report = this.hyShippingLntaxReportService.getByShippingNoteNumber(hyShippingNote.getShippingNoteNumber());
        if (null == report) {
            report = new HyShippingLntaxReport();
            report.setShippingNoteNumber(hyShippingNote.getShippingNoteNumber());
            report.setCreateTime(new Date());
        }

        //判断挂车是否存在，如果不存在需要补传
        if (StrUtil.isNotEmpty(hyVehicle.getTrailerVehiclePlateNumber()) && hyVehicle.getTrailerVehiclePlateNumber().contains("挂")) {
            AlctApiBaseResDTO vStatus = this.oapiAlct56Service.queryVehicle(hyVehicle.getTrailerVehiclePlateNumber());
            if (!"0".equals(vStatus.getCode())) {
                VehicleDTO trailerVehicleDTO = new VehicleDTO();
                trailerVehicleDTO.setLicensePlateNo(hyVehicle.getTrailerVehiclePlateNumber());
                trailerVehicleDTO.setPlateNoColor(hyVehicle.getVehiclePlateColorCode());
                trailerVehicleDTO.setStandardVehicleType("重型普通半挂车");//	车辆类型	字符串	最长20为	否
                trailerVehicleDTO.setVehicleIdentityCode(hyVehicle.getVin());//	车架号	字符	17位	是	17位数字与字母组合
                trailerVehicleDTO.setOwner(hyVehicle.getOwner());
                trailerVehicleDTO.setLoad(hyVehicle.getVehicleTonnage().intValue() * 1000);
                trailerVehicleDTO.setUsage("货运");
                log.info("辽宁税务上传挂车信息 -> {}", JSONUtil.toJsonStr(trailerVehicleDTO));
                this.oapiAlct56Service.submitVehicle(trailerVehicleDTO);
            }

            Map<String, String> dto = new HashMap<>();
            dto.put("header", hyVehicle.getVehicleNumber());
            dto.put("body", hyVehicle.getTrailerVehiclePlateNumber());
            log.info("辽宁税务上传车头与挂车绑定信息 -> {}", JSONUtil.toJsonStr(dto));
            this.oapiAlct56Service.submitVehicleTrailer(dto);
        }

        BodyDTO bodyDTO = getBodyDTO(hyShippingNote, hyOrder, hyVehicle, hyDriver, hyCustomer);
        AlctApiBaseResDTO result = oapiAlct56Service.createShippingNote(bodyDTO);
        if (result.getCode().equalsIgnoreCase("200")) {
            report.setLntaxUploadStatus("1");
            report.setLntaxUploadDate(new Date());
            report.setLntaxFailureReason("上报成功");
            hyShippingLntaxReportService.saveOrUpdate(report);
            return Result.OK("操作成功");
        }

        report.setLntaxUploadStatus(result.getCode());
        report.setLntaxUploadDate(new Date());
        report.setLntaxFailureReason(result.getMessage());
        hyShippingLntaxReportService.saveOrUpdate(report);
        return Result.error(result.getMessage());
    }


    /**
     * 补录历史运单
     */
    public Result uploadHistoryShippingNote(HyShippingNote hyShippingNote) {

        HyOrder hyOrder = orderService.getById(hyShippingNote.getOrderId());
        if (hyOrder == null) {
            throw new JeecgBootException("该运单货源信息不能为空");
        }

        HyVehicle hyVehicle = vehicleService.getById(hyShippingNote.getVehicleId());
        if (hyVehicle == null) {
            throw new JeecgBootException("该运单车辆信息不能为空");
        }
        HyDriver hyDriver = driverService.getById(hyShippingNote.getDriverId());
        if (hyDriver == null) {
            throw new JeecgBootException("该运单司机信息不能为空");
        }

        HyCustomer hyCustomer = customerService.getById(hyShippingNote.getCustomerId());
        if (hyCustomer == null) {
            throw new JeecgBootException("该运单货主信息不能为空");
        }

        HistoryDataBodyDTO bodyDTO = getHistoryBodyDTO(hyShippingNote, hyOrder, hyVehicle, hyDriver, hyCustomer);

        AlctApiBaseResDTO result = oapiAlct56Service.uploadHistoryShippingNote(bodyDTO);
        if (!result.getCode().equalsIgnoreCase("0")) {
            return Result.error(result.getMessage());
        }

        return Result.OK("上传成功");
    }



    /**
     * 辽宁税务查询司机是否已经实名认证，如果没认证不允许接单
     * @param hyDriver
     * @return
     */
    public Result queryDriverForAuth(HyDriver hyDriver) {

        String identityNo = hyDriver.getIdcard();
        log.info("查询司机状态请求 -> {} {}", hyDriver.getDriverName(), identityNo);
        AlctApiBaseResDTO result = oapiAlct56Service.getDriverStatus("/api/v1/openapi/drivers?identityNo=", identityNo);
        if (!"0".equals(result.getCode())) {
            if (result.getMessage().contains("司机不存在")) {
                return Result.error("税务系统中该司机不存在,请联系管理员上报司机信息");
            }
            return Result.error("税务系统返回错误: " + result.getMessage());
        }

        //待实名的司机需要返回实名认证URL，让APP跳转到辽宁税务小程序进行实名认证
        JSONObject jsonObject = JSONUtil.parseObj(result.getDriver());
        //待实名是V
        if ("V".equals(jsonObject.getStr("taxRegisterStatus"))) {
            AlctApiBaseResDTO result2 = oapiAlct56Service.getDriverAuthUrl(identityNo);
            if (!"0".equals(result2.getCode())) {
                return Result.error(result2.getMessage());
            }

            //如果辽宁税务返回成功了，系统给前端返回特殊错误码，表示需要司机APP进行微信实名认证操作
            // {"result":"weixin://dl/business/?t=IjEyTxLwXCm","code":"0","message":"success"}
            return Result.error(-3, result2.getResult());
        }

        //待税登是N
        if ("N".equals(jsonObject.getStr("taxRegisterStatus"))) {
            return Result.error(-2, "已实名认证，待税登");
        }

        //税登申请中是A
        if ("A".equals(jsonObject.getStr("taxRegisterStatus"))) {
            return Result.error(-1, "税登申请中");
        }

        //已驳回是R
        if ("R".equals(jsonObject.getStr("taxRegisterStatus"))) {
            return Result.error(-4, "税登状态已驳回");
        }

        //待税费种认定
        if ("C".equals(jsonObject.getStr("taxRegisterStatus"))) {
            return Result.error(-5, "待税费种认定");
        }

        return Result.OK("已税登");
    }


    /**
     * 陆交开放平台 组装创建运单数据
     *
     * @param hyShippingNote
     * @return
     */
    private BodyDTO getBodyDTO(HyShippingNote hyShippingNote, HyOrder hyOrder, HyVehicle hyVehicle, HyDriver hyDriver,
            HyCustomer hyCustomer) {
        BodyDTO bodyDTO = new BodyDTO();
        bodyDTO.setShippingNoteNumber(hyShippingNote.getShippingNoteNumber());
        if (ObjectUtil.isEmpty(hyShippingNote.getCreateTime())) {
            bodyDTO.setConsignmentDateTime(DateUtils.dateTimeToStringT(new Date()));
        } else {
            bodyDTO.setConsignmentDateTime(DateUtils.dateTimeToStringT(hyShippingNote.getCreateTime()));
        }
        bodyDTO.setPickupLocation(hyShippingNote.getSendAddress());
        bodyDTO.setPickupCountrySubdivisionCode(Integer.valueOf(hyShippingNote.getSendAreaCode()));
        bodyDTO.setUnloadLocation(hyShippingNote.getReceiveAddress());
        bodyDTO.setUnloadCountrySubdivisionCode(Integer.valueOf(hyShippingNote.getReceiveAreaCode()));

        //Added start at 2023-12-25 for 辽宁税务航信平台新增字段,收发货坐标
        if (null == hyShippingNote.getSendLongitude() || null == hyShippingNote.getSendLatitude()) {
            String sendLngLat = this.amapService.coordinate(hyShippingNote.getSendAddress());
            if (StrUtil.isEmpty(sendLngLat) || sendLngLat.split(",").length < 2) {
                throw new JeecgBootException("发货地址坐标转换失败，请确认发货地址");
            }
            double[] coordinate = LngLonUtil.gcj02_To_Bd09(Double.valueOf(sendLngLat.split(",")[1]), Double.valueOf(sendLngLat.split(",")[0]));
            bodyDTO.setPickupLng(coordinate[1]);
            bodyDTO.setPickupLat(coordinate[0]);
        } else {
            bodyDTO.setPickupLng(hyShippingNote.getSendLongitude().doubleValue());
            bodyDTO.setPickupLat(hyShippingNote.getSendLatitude().doubleValue());
        }

        if (null == hyShippingNote.getReceiveLongitude() || null == hyShippingNote.getReceiveLatitude()) {
            String recvLngLat = this.amapService.coordinate(hyShippingNote.getReceiveAddress());
            if (StrUtil.isEmpty(recvLngLat) || recvLngLat.split(",").length < 2) {
                throw new JeecgBootException("收货地址坐标转换失败，请确认收货地址");
            }
            double[] coordinate = LngLonUtil.gcj02_To_Bd09(Double.valueOf(recvLngLat.split(",")[1]), Double.valueOf(recvLngLat.split(",")[0]));
            bodyDTO.setUnloadLng(coordinate[1]);
            bodyDTO.setUnloadLat(coordinate[0]);
        } else {
            bodyDTO.setUnloadLng(hyShippingNote.getReceiveLongitude().doubleValue());
            bodyDTO.setUnloadLat(hyShippingNote.getReceiveLatitude().doubleValue());
        }

        bodyDTO.setTransportContractNo("未生成");
        bodyDTO.setTransportContractPrice(0L);
        if (StrUtil.isNotEmpty(hyVehicle.getTrailerVehiclePlateNumber()) && hyVehicle.getTrailerVehiclePlateNumber().contains("挂")) {
            bodyDTO.setTrailerVehicleNumber(hyVehicle.getTrailerVehiclePlateNumber());
        }
        //Added end at 2023-12-25

//        bodyDTO.setDistance(Double.valueOf(hyShippingNote.getTransportationDistance()));
//        bodyDTO.setPlanPickupTimeStart(DateUtils.dateTimeToStringT(hyShippingNote.getSendDate()));
//        bodyDTO.setPlanPickupTimeEnd(DateUtils.dateTimeToStringT(hyShippingNote.getSendDate()));
//        bodyDTO.setPlanUnloadTimeStart(DateUtils.dateTimeToStringT(hyShippingNote.getReceiveDate()));
//        bodyDTO.setPlanUnloadTimeEnd(DateUtils.dateTimeToStringT(hyShippingNote.getReceiveDate()));

        //Modified at 2023-08-31 for 增加模拟轨迹计算公里数
        MapDirectionDTO mapDirectionDTO = this.amapService.getMapGpsOrder(hyOrder);
        if (ObjectUtil.isEmpty(mapDirectionDTO)) {
            throw new JeecgBootException("高德轨迹数据不正确，请确认收发货地址");
        }
        bodyDTO.setDistance(Double.valueOf(mapDirectionDTO.getDistance()));

        bodyDTO.setDriverIdentification(hyDriver.getIdcard());
        bodyDTO.setVehicleNumber(hyVehicle.getVehicleNumber());
        //bodyDTO.setTotalWeight(hyOrder.getTotalGoodsWeight().doubleValue());
        bodyDTO.setTotalWeight(0d);
        bodyDTO.setTotalCube(0d);

        PriceInfoDTO priceInfoDTO = new PriceInfoDTO();

        //BigDecimal num = new BigDecimal("100");
        //Long fee = hyOrder.getShippingUnitPrice().multiply(num).setScale(0, BigDecimal.ROUND_DOWN).longValue();
        //priceInfoDTO.setPrice(fee);
        priceInfoDTO.setPrice(0L);
        bodyDTO.setPriceInfo(priceInfoDTO);

        List <GoodsInfoDTO> goodsInfoDTOS = new ArrayList <>();
        GoodsInfoDTO goodsInfoDTO = new GoodsInfoDTO();
        goodsInfoDTO.setDescriptionOfGoods(hyShippingNote.getDescriptionOfGoods());

        String cargoType = hyShippingNote.getCargoTypeClassificationCode();
        CargoTypeEnum cargoTypeEnum = CargoTypeEnum.getCargoTypeEnumByVal(cargoType);
        goodsInfoDTO.setGoodsPropertyTypeCode(Integer.valueOf(cargoTypeEnum.getCargoClass()));
        goodsInfoDTO.setUnitWight(hyVehicle.getVehicleTonnage().doubleValue() * 1000);
        goodsInfoDTO.setUnitVol(0d);

        goodsInfoDTOS.add(goodsInfoDTO);
        bodyDTO.setGoodsInfo(goodsInfoDTOS);

        //收货人信息
        ConsigneeInfoDTO consigneeInfoDTO = new ConsigneeInfoDTO();
        consigneeInfoDTO.setConsignee(hyShippingNote.getReceiveContactName());
        consigneeInfoDTO.setCustomerName(hyShippingNote.getReceiveContactName());
        //TODO 这里需要优化，因为系统目前没有收货人身份证号
        consigneeInfoDTO.setIdentificationNumberOfTheTaxpayer(hyCustomer.getIdcard());
        consigneeInfoDTO.setTelephone(hyShippingNote.getReceiveContactTel());
        bodyDTO.setConsigneeInfo(consigneeInfoDTO);
        //发货人信息
        ConsignorInfoDTO consignorInfoDTO = new ConsignorInfoDTO();
        consignorInfoDTO.setConsigner(hyShippingNote.getSendContactName());
        consignorInfoDTO.setCustomerName(hyCustomer.getCustomerName());
        consignorInfoDTO.setIdentificationNumberOfTheTaxpayer("2".equals(hyCustomer.getCustomerType()) ? hyCustomer.getCreditCode() : hyCustomer.getIdcard());
        consignorInfoDTO.setTelephone(hyShippingNote.getSendContactTel());
        bodyDTO.setConsignorInfo(consignorInfoDTO);
        return bodyDTO;
    }


    /**
     * 陆交开放平台 组装历史运单数据
     *
     * @param hyShippingNote
     * @return
     */
    private HistoryDataBodyDTO getHistoryBodyDTO(HyShippingNote hyShippingNote, HyOrder hyOrder, HyVehicle hyVehicle, HyDriver hyDriver,
                               HyCustomer hyCustomer) {
        HistoryDataBodyDTO bodyDTO = new HistoryDataBodyDTO();
        bodyDTO.setShippingNoteNumber(hyShippingNote.getShippingNoteNumber());
        if (ObjectUtil.isEmpty(hyShippingNote.getCreateTime())) {
            bodyDTO.setConsignmentDateTime(DateUtils.dateTimeToStringT(new Date()));
        } else {
            bodyDTO.setConsignmentDateTime(DateUtils.dateTimeToStringT(hyShippingNote.getCreateTime()));
        }
        bodyDTO.setPickupLocation(hyShippingNote.getSendAddress());
        bodyDTO.setPickupCountrySubdivisionCode(Integer.valueOf(hyShippingNote.getSendAreaCode()));
        bodyDTO.setUnloadLocation(hyShippingNote.getReceiveAddress());
        bodyDTO.setUnloadCountrySubdivisionCode(Integer.valueOf(hyShippingNote.getReceiveAreaCode()));

        bodyDTO.setPickupLng(hyShippingNote.getSendLongitude().doubleValue());
        bodyDTO.setPickupLat(hyShippingNote.getSendLatitude().doubleValue());

        bodyDTO.setUnloadLng(hyShippingNote.getReceiveLongitude().doubleValue());
        bodyDTO.setUnloadLat(hyShippingNote.getReceiveLatitude().doubleValue());

        bodyDTO.setTransportContractNo(hyShippingNote.getContractNum());
        bodyDTO.setTransportContractPrice(hyShippingNote.getDriverFee().longValue());
        bodyDTO.setTrailerVehicleNumber(hyVehicle.getTrailerVehiclePlateNumber());

        String vehicleNumber = hyVehicle.getVehicleNumber();
        String startTime = DateUtils.dateTimeToString(hyShippingNote.getStatusDtLoading());
        String endTime = DateUtils.dateTimeToString(hyShippingNote.getStatusDtUnloading());
        String vehicleColor = StringUtils.isNotEmpty(hyVehicle.getVehiclePlateColorCode()) ? hyVehicle.getVehiclePlateColorCode() : "2";
        WaybillRouteVO waybillRouteVO = this.waybillRouteService.getWaybillRoute(vehicleNumber, vehicleColor, startTime, endTime, "Baidu");
//        //Modified at 2023-08-31 for 增加模拟轨迹计算公里数
//        MapDirectionDTO mapDirectionDTO = this.amapService.getMapGpsOrder(hyOrder);
//        if (ObjectUtil.isEmpty(mapDirectionDTO)) {
//            throw new JeecgBootException("高德轨迹数据不正确，请确认收发货地址");
//        }
        bodyDTO.setDistance(Double.valueOf(waybillRouteVO.getMileage()));

        bodyDTO.setDriverIdentification(hyDriver.getIdcard());
        bodyDTO.setVehicleNumber(hyVehicle.getVehicleNumber());
        bodyDTO.setTotalWeight(hyShippingNote.getGoodsWeightUnloading().doubleValue());
        bodyDTO.setTotalCube(0d);
        bodyDTO.setStatus("70");
        bodyDTO.setFirstPickUpDate(DateUtils.dateTimeToStringT(hyShippingNote.getStatusDtLoading()));
        bodyDTO.setLastArrivatedTime(DateUtils.dateTimeToStringT(hyShippingNote.getStatusDtUnloading()));
        bodyDTO.setSigneeReceiveTime(DateUtils.dateTimeToStringT(hyShippingNote.getStatusDtSign()));
        bodyDTO.setSignee(hyCustomer.getLegalName());
        bodyDTO.setReceiptTime(DateUtils.dateTimeToStringT(hyShippingNote.getStatusDtSign()));
        bodyDTO.setReceiptBy(hyCustomer.getLegalName());
        bodyDTO.setReceiptNo(hyShippingNote.getShippingNoteNumber());

        //价格
        PriceInfoDTO priceInfoDTO = new PriceInfoDTO();
        BigDecimal num = new BigDecimal("100");
        Long fee = hyShippingNote.getDriverFee().multiply(num).setScale(0, BigDecimal.ROUND_DOWN).longValue();
        priceInfoDTO.setPrice(fee);
        bodyDTO.setPriceInfo(priceInfoDTO);

        //货物信息
        List<GoodsInfoDTO> goodsInfoDTOS = new ArrayList <>();
        GoodsInfoDTO goodsInfoDTO = new GoodsInfoDTO();
        goodsInfoDTO.setDescriptionOfGoods(hyShippingNote.getDescriptionOfGoods());
        String cargoType = hyShippingNote.getCargoTypeClassificationCode();
        CargoTypeEnum cargoTypeEnum = CargoTypeEnum.getCargoTypeEnumByVal(cargoType);
        goodsInfoDTO.setGoodsPropertyTypeCode(Integer.valueOf(cargoTypeEnum.getCargoClass()));
        goodsInfoDTO.setUnitWight(hyVehicle.getVehicleTonnage().doubleValue() * 1000);
        goodsInfoDTO.setUnitVol(0d);
        goodsInfoDTOS.add(goodsInfoDTO);
        bodyDTO.setGoodsInfo(goodsInfoDTOS);

        //收货人信息
        ConsigneeInfoDTO consigneeInfoDTO = new ConsigneeInfoDTO();
        consigneeInfoDTO.setConsignee(hyShippingNote.getReceiveContactName());
        consigneeInfoDTO.setCustomerName(hyShippingNote.getReceiveContactName());
        //TODO 这里需要优化，因为系统目前没有收货人身份证号
        consigneeInfoDTO.setIdentificationNumberOfTheTaxpayer(hyCustomer.getIdcard());
        consigneeInfoDTO.setTelephone(hyShippingNote.getReceiveContactTel());
        bodyDTO.setConsigneeInfo(consigneeInfoDTO);
        //发货人信息
        ConsignorInfoDTO consignorInfoDTO = new ConsignorInfoDTO();
        consignorInfoDTO.setConsigner(hyShippingNote.getSendContactName());
        consignorInfoDTO.setCustomerName(hyCustomer.getCustomerName());
        consignorInfoDTO.setIdentificationNumberOfTheTaxpayer("2".equals(hyCustomer.getCustomerType()) ? hyCustomer.getCreditCode() : hyCustomer.getIdcard());
        consignorInfoDTO.setTelephone(hyShippingNote.getSendContactTel());
        bodyDTO.setConsignorInfo(consignorInfoDTO);

        //轨迹
        List<TracesInfoDTO> tracesInfoDTOS;
        String vehicleTrackSwitch = this.settingService.getSettingValueByTag2("vehicle_track_switch");
        if ("1".equals(vehicleTrackSwitch)) {
            tracesInfoDTOS = getTracesList(hyVehicle, hyShippingNote);
            if (CollectionUtils.isEmpty(tracesInfoDTOS)) {
                throw new JeecgBootException("该运单轨迹信息不存在");
            }
        } else {
            //如果开启模拟轨迹
            tracesInfoDTOS = getSimulateTracesList(hyShippingNote);
        }

        List<HistoryTracesInfoDTO> historyTracesInfoDTOS = new ArrayList<>();
        tracesInfoDTOS.forEach( s-> {
            HistoryTracesInfoDTO item = new HistoryTracesInfoDTO();
            item.setCooridnationType("Baidu");
            item.setTime(s.getTime());
            item.setLongitude(s.getLongitude().setScale(7, BigDecimal.ROUND_HALF_UP));
            item.setLatitude(s.getLatitude().setScale(7, BigDecimal.ROUND_HALF_UP));
            historyTracesInfoDTOS.add(item);
        });
        bodyDTO.setWtraces(historyTracesInfoDTOS);

        //图片
        List<ImagesDTO> imagesDTOS = new ArrayList<>();
        //装货照片
        ImagesDTO loadingImage = new ImagesDTO();
        String prefix = hyShippingNote.getLoadingSceneImg().substring(hyShippingNote.getLoadingSceneImg().lastIndexOf('.') + 1);
        String base64 = ImageUtil.imgageToBase64(uploadpath + "/" + hyShippingNote.getLoadingSceneImg(), prefix);
        loadingImage.setImageType("pickup");
        loadingImage.setFileExt(prefix);
        loadingImage.setFileName("pickup_" + System.currentTimeMillis());
        loadingImage.setFileData(base64);
        imagesDTOS.add(loadingImage);

        //卸货照片
        ImagesDTO unloadingImage = new ImagesDTO();
        String prefix2 = hyShippingNote.getUnloadingSceneImg().substring(hyShippingNote.getUnloadingSceneImg().lastIndexOf('.') + 1);
        String base642 = ImageUtil.imgageToBase64(uploadpath + "/" + hyShippingNote.getUnloadingSceneImg(), prefix);
        unloadingImage.setImageType("unload");
        unloadingImage.setFileExt(prefix2);
        unloadingImage.setFileName("unload_" + System.currentTimeMillis());
        unloadingImage.setFileData(base642);
        imagesDTOS.add(unloadingImage);

        //回单照片
        ImagesDTO podImage = new ImagesDTO();
        String prefix3 = hyShippingNote.getImgUnloading().substring(hyShippingNote.getImgUnloading().lastIndexOf('.') + 1);
        String base643 = ImageUtil.imgageToBase64(uploadpath + "/" + hyShippingNote.getImgUnloading(), prefix);
        podImage.setImageType("pod");
        podImage.setFileExt(prefix3);
        podImage.setFileName("pod_" + System.currentTimeMillis());
        podImage.setFileData(base643);
        imagesDTOS.add(podImage);
        bodyDTO.setWimgs(imagesDTOS);

        bodyDTO.setDrivers("{}");
        bodyDTO.setTrucks("{}");

        return bodyDTO;
    }


    /**
     * 陆交开放平台 取消运单
     *
     * @param hyShippingNote
     * @return
     */

    public boolean cancelShippingNote(HyShippingNote hyShippingNote) {
        HyShippingNote hyShippingNoteDb = hyShippingNoteService.getByShippingNoteNumer(hyShippingNote.getShippingNoteNumber());
        if (hyShippingNoteDb == null) {
            throw new JeecgBootException("未找到对应数据");
        }
        if (!"1".equals(hyShippingNoteDb.getAlctIdentification())) {
            throw new JeecgBootException("该运单不属于辽宁税务运单");
        }
        AlctApiBaseResDTO result = oapiAlct56Service.cancelShippingNote(hyShippingNoteDb.getShippingNoteNumber());
        if(result == null){
            throw new JeecgBootException("系统异常,请重新操作");
        }
        if(!"0".equals(result.getCode())){
            throw new JeecgBootException(result.getMessage());
        }
        return true;
    }

    /**
     * 陆交开放平台 已支付运单更新运费
     *
     * @param hyShippingNote
     * @return
     */

    public Result updatePriceAndContract(HyShippingNote hyShippingNote) {
        HyShippingNote hyShippingNoteDb = hyShippingNoteService.getById(hyShippingNote.getId());
        if (hyShippingNoteDb == null) {
            throw new JeecgBootException("未找到对应数据");
        }
        if (!hyShippingNoteDb.getAlctIdentification().equals("1")) {
            throw new JeecgBootException("该运单不属于辽宁税务运单");
        }


        HyShippingLntaxReport report = this.hyShippingLntaxReportService.getByShippingNoteNumber(hyShippingNote.getShippingNoteNumber());
        if (null == report) {
            throw new JeecgBootException("未找到运单上报记录");
        }

        UpdatepriceDTO updatepriceDTO = new UpdatepriceDTO();
        updatepriceDTO.setShipmentCode(hyShippingNoteDb.getShippingNoteNumber());
        BigDecimal num = new BigDecimal("100");
        //price: 单位为分，为整数
        Integer fee = hyShippingNoteDb.getDriverFee().multiply(num).setScale(0, BigDecimal.ROUND_DOWN).intValue();
        updatepriceDTO.setPrice(fee);
        updatepriceDTO.setComments(hyShippingNote.getId());
//        updatepriceDTO.setComments(hyShippingNoteBill.getBillNum());
        // Added at 2023-12-25 for 对账完成后更新合同以及卸货重量或体积
        HyOrder order = this.orderService.getById(hyShippingNoteDb.getOrderId());
        if ("1".equals(order.getGoodsUnit())) {
            //按吨
            updatepriceDTO.setTotalWeight(hyShippingNoteDb.getGoodsWeightUnloading().toString());
        } else if ("3".equals(order.getGoodsUnit())) {
            //按立方
            updatepriceDTO.setTotalCube(hyShippingNoteDb.getGoodsWeightUnloading().toString());
        } else {
            throw new JeecgBootException("货源货物单位不正确,请修改为吨或立方");
        }

        if (StrUtil.isEmpty(hyShippingNoteDb.getContractNum()) || StrUtil.isEmpty(hyShippingNoteDb.getShippingContract())) {
            throw new JeecgBootException("该运单未生成合同，请先生成运输合同");
        }
        updatepriceDTO.setTransportContractNo(hyShippingNoteDb.getContractNum());
        updatepriceDTO.setTransportContractPrice(fee.longValue());

        AlctApiBaseResDTO result = oapiAlct56Service.updatePrice(updatepriceDTO);
        // 如果提示已开票不能修改运费也认为它成功了，跳过该步骤{"code":"OB013501","message":"运单已经生成过发票，不能修改运费"}
        if (!result.getCode().equals("0") && !result.getCode().equals("OB013501")) {
            report.setLntaxbalanceUploadStatus(result.getCode());
            report.setLntaxbalanceUploadDate(new Date());
            report.setLntaxbalanceFailueReason(result.getMessage());
            this.hyShippingLntaxReportService.updateById(report);
            return Result.error(result.getMessage());
        }

        AlctApiBaseResDTO result2 = oapiAlct56Service.uploadContract(
                hyShippingNoteDb.getShippingNoteNumber(),
                hyShippingNoteDb.getContractNum(),
                hyShippingNoteDb.getShippingContract());
        if (!result2.getCode().equals("0")) {
            report.setLntaxbalanceUploadStatus(result2.getCode());
            report.setLntaxbalanceUploadDate(new Date());
            report.setLntaxbalanceFailueReason(result2.getMessage());
            this.hyShippingLntaxReportService.updateById(report);
            return Result.error(result2.getMessage());
        }

        report.setLntaxbalanceUploadStatus("1");
        report.setLntaxbalanceUploadDate(new Date());
        report.setLntaxbalanceFailueReason("上报成功");
        this.hyShippingLntaxReportService.updateById(report);
        return Result.OK();
    }


    /**
     * 上传银行回单
     */
    public Result uploadBankReceipt(LnTaxShippingNoteDTO lnTaxShippingNote) {

        HyShippingLntaxReport report = this.hyShippingLntaxReportService.getByShippingNoteNumber(lnTaxShippingNote.getShippingNoteNumber());
        if (null == report) {
            return Result.error("未找到运单上报记录");
        }

        HyShippingNoteBill hyShippingNoteBill = hyShippingNoteBillService.getBillByShippingId(lnTaxShippingNote.getId());
        if (null == hyShippingNoteBill) {
            return Result.error(report.getShippingNoteNumber() + " ,该运单未支付，请确认支付状态");
        }

        //如果前端传了图片，用前端现成的。如果前端没有传，用数据库里存的回单
        String bankHdImg = StrUtil.EMPTY;
        if (StrUtil.isNotEmpty(lnTaxShippingNote.getBankImage())) {
            bankHdImg = this.uploadpath + File.separator + lnTaxShippingNote.getBankImage();
        } else {
            //这个判断分支几乎不能进入，因为前端显示的就是bankHdImg字段，所以前端BankImage必定有值
            if (StrUtil.isEmpty(hyShippingNoteBill.getBankHdImg())) {
                log.error("该运单未找到银行回单, {}", hyShippingNoteBill.getBankHdImg());
                return Result.error(hyShippingNoteBill.getShippingNoteNumber() + " ,该运单未找到银行回单");
            }

            bankHdImg = this.uploadpath + File.separator + hyShippingNoteBill.getBankHdImg();
        }

        BankReceiptDTO bankReceiptDTO = BankReceiptDTO.builder()
                .shipmentCode(hyShippingNoteBill.getShippingNoteNumber())
                .shipmentPrice(hyShippingNoteBill.getAmt().multiply(new BigDecimal("100")).longValue())
                .transportContractNo(lnTaxShippingNote.getContractNum())
                .transportContractPrice(hyShippingNoteBill.getAmt().multiply(new BigDecimal("100")).longValue())
                .bankCode(hyShippingNoteBill.getBillNum())
                .build();

        //返回值错误，并且提示的不是【回执单已存在】错误，前端才提示错误
        AlctApiBaseResDTO result = this.oapiAlct56Service.uploadBankReceipt(bankReceiptDTO);
        if (!result.getCode().equals("0") && !result.getMessage().contains("回执单已存在")) {
            report.setLntaxbankUploadStatus(result.getCode());
            report.setLntaxbankUploadDate(new Date());
            report.setLntaxbankFailureReason(result.getMessage());
            this.hyShippingLntaxReportService.updateById(report);
            return Result.error(result.getMessage());
        }

        AlctApiBaseResDTO result2 = this.oapiAlct56Service.uploadBankReceiptFile(hyShippingNoteBill.getShippingNoteNumber(), bankHdImg);
        if (!result2.getCode().equals("0")) {
            report.setLntaxbankUploadStatus(result2.getCode());
            report.setLntaxbankUploadDate(new Date());
            report.setLntaxbankFailureReason(result2.getMessage());
            this.hyShippingLntaxReportService.updateById(report);
            return Result.error(result2.getMessage());
        }

        report.setLntaxbankUploadStatus("1");
        report.setLntaxbankUploadDate(new Date());
        report.setLntaxbankFailureReason("上报成功");
        this.hyShippingLntaxReportService.updateById(report);
        return Result.OK("操作成功");
    }



    /**
     * 陆交开放平台  同步已完成运单的车辆轨迹数据
     *
     * @param hyShippingNote
     * @return
     */
    public Result syncTraces(HyShippingNote hyShippingNote) {
        HyShippingNote hyShippingNoteDb = hyShippingNoteService.getById(hyShippingNote.getId());
        if (hyShippingNoteDb == null) {
            throw new JeecgBootException("未找到对应数据");
        }

        if (!hyShippingNoteDb.getAlctIdentification().equals("1")) {
            throw new JeecgBootException("该运单不属于辽宁税务运单");
        }

        log.info("同步辽宁税务轨迹，当前运单状态 {} {}", hyShippingNoteDb.getShippingNoteNumber(), hyShippingNoteDb.getShippingStatus());

        HyVehicle hyVehicle = vehicleService.getById(hyShippingNoteDb.getVehicleId());
        if (hyVehicle == null) {
            throw new JeecgBootException("该运单车辆信息不存在");
        }

        List<TracesInfoDTO> tracesInfoDTOS;
        String vehicleTrackSwitch = this.settingService.getSettingValueByTag2("vehicle_track_switch");
        if ("1".equals(vehicleTrackSwitch)) {
            tracesInfoDTOS = getTracesList(hyVehicle, hyShippingNoteDb);
            if (CollectionUtils.isEmpty(tracesInfoDTOS)) {
                throw new JeecgBootException("该运单轨迹信息不存在");
            }
        } else {
            //如果开启模拟轨迹
            tracesInfoDTOS = getSimulateTracesList(hyShippingNoteDb);
        }

        HyShippingLntaxReport report = this.hyShippingLntaxReportService.getByShippingNoteNumber(hyShippingNote.getShippingNoteNumber());
        if (null == report) {
            return Result.error("未找到运单上报记录");
        }

        TracesDTO tracesDTO = new TracesDTO();
        tracesDTO.setShipmentCode(hyShippingNoteDb.getShippingNoteNumber());
        tracesDTO.setCooridnationType("Baidu");
        tracesDTO.setTraces(tracesInfoDTOS);
        log.warn("同步轨迹信息， {} {} {}", tracesDTO.getShipmentCode(), tracesDTO.getCooridnationType(), tracesDTO.getTraces().size());
        AlctApiBaseResDTO result = oapiAlct56Service.syncTraces(tracesDTO);
        if (result.getCode().equals("0") || result.getMessage().contains("重复") || result.getMessage().contains("已存在")) {
            report.setLntaxtraceUploadStatus("1");
            report.setLntaxtraceUploadDate(new Date());
            report.setLntaxtraceFailureReason("上报成功");
            this.hyShippingLntaxReportService.updateById(report);
            return Result.OK("操作成功");
        }

        report.setLntaxtraceUploadStatus(result.getCode());
        report.setLntaxtraceUploadDate(new Date());
        report.setLntaxtraceFailureReason(result.getMessage());
        this.hyShippingLntaxReportService.updateById(report);
        return Result.error(result.getMessage());
    }


    private List<TracesInfoDTO> getSimulateTracesList(HyShippingNote hyShippingNote) {
        List<TracesInfoDTO> gpsDTOS = new ArrayList<>();
        List<GpsDTO> gpsDTOList = this.amapService.getMapGps(hyShippingNote);

        if (CollUtil.isEmpty(gpsDTOList)) {
            log.info("获取模拟轨迹，当前运单{}无轨迹点数", hyShippingNote.getShippingNoteNumber());
            return gpsDTOS;
        }

        log.info("获取模拟轨迹，当前运单{} 轨迹点数{}", hyShippingNote.getShippingNoteNumber(), gpsDTOList.size());
        int a = gpsDTOList.size();
        if (a <= 1000) {
            for (GpsDTO dto : gpsDTOList) {
                TracesInfoDTO gpsDTO = new TracesInfoDTO();
                double[] coordinate = LngLonUtil.gcj02_To_Bd09(Double.valueOf(dto.getLat()), Double.valueOf(dto.getLon()));
                gpsDTO.setLongitude(new BigDecimal(coordinate[1]).setScale(5, RoundingMode.DOWN));
                gpsDTO.setLatitude(new BigDecimal(coordinate[0]).setScale(5, RoundingMode.DOWN));
                gpsDTO.setTime(
                        DateUtils.dateTimeToStringT(DateUtils.stringToDateTime(dto.getPositionTime())));
                gpsDTOS.add(gpsDTO);
            }
        } else {
            int b = getFrequency(a);
            int n = 1;
            for (GpsDTO dto : gpsDTOList) {
                if (n % b == 0) {
                    TracesInfoDTO gpsDTO = new TracesInfoDTO();
                    double[] coordinate = LngLonUtil.gcj02_To_Bd09(Double.valueOf(dto.getLat()), Double.valueOf(dto.getLon()));
                    gpsDTO.setLongitude(new BigDecimal(coordinate[1]).setScale(5, RoundingMode.DOWN));
                    gpsDTO.setLatitude(new BigDecimal(coordinate[0]).setScale(5, RoundingMode.DOWN));
                    gpsDTO.setTime(DateUtils.dateTimeToStringT(DateUtils.stringToDateTime(dto.getPositionTime())));
                    gpsDTOS.add(gpsDTO);
                }
                n++;
            }
        }

        return gpsDTOS;
    }

    /**
     * 陆交开放平台  同步运单的车辆轨迹数据
     *
     * @param hyVehicle
     * @param hyShippingNote
     * @return
     */
    private List<TracesInfoDTO> getTracesList(HyVehicle hyVehicle, HyShippingNote hyShippingNote) {
        List<TracesInfoDTO> gpsDTOS = new ArrayList<>();
        String startTime = DateUtils.dateTimeToString(hyShippingNote.getStatusDtLoading());
        String endTime = DateUtils.dateTimeToString(hyShippingNote.getStatusDtUnloading());
        //如果超出了收发货时间，税务系统会自动抛弃，所以用new date不会有问题
        if (StrUtil.isEmpty(endTime)) {
            endTime = DateUtils.dateTimeToString(new Date());
        }
        String vehicleColor = StringUtils.isNotEmpty(hyVehicle.getVehiclePlateColorCode()) ? hyVehicle.getVehiclePlateColorCode() : "2";
        WaybillRouteVO waybillRouteVO = waybillRouteService.getWaybillRoute(hyVehicle.getVehicleNumber(), vehicleColor, startTime, endTime, "BD09");
        if (waybillRouteVO != null && CollectionUtils.isNotEmpty(waybillRouteVO.getPointDataList())) {
            List<PointDataListVO> pointDataListVOS = waybillRouteVO.getPointDataList();
            int a = pointDataListVOS.size();

            if (a <= 1000) {
                for (PointDataListVO pointDataListVO : pointDataListVOS) {
                    TracesInfoDTO gpsDTO = new TracesInfoDTO();
                    //double[] coordinate = LngLonUtil.gcj02_To_Bd09(Double.valueOf(pointDataListVO.getLat()), Double.valueOf(pointDataListVO.getLng()));

                    gpsDTO.setLongitude(new BigDecimal(pointDataListVO.getLng()));
                    gpsDTO.setLatitude(new BigDecimal(pointDataListVO.getLat()));
                    //gpsDTO.setLatitude(new BigDecimal(pointDataListVO.getLat()).setScale(6, BigDecimal.ROUND_DOWN));
                    gpsDTO.setTime(
                            DateUtils.dateTimeToStringT(DateUtils.stringToDateTime(pointDataListVO.getReceiveTime())));
                    gpsDTOS.add(gpsDTO);
                }
            } else {
                int b = getFrequency(a);
                int n = 1;
                for (PointDataListVO pointDataListVO : pointDataListVOS) {
                    if (n % b == 0) {
                        TracesInfoDTO gpsDTO = new TracesInfoDTO();
                        //double[] coordinate = LngLonUtil.gcj02_To_Bd09(Double.valueOf(pointDataListVO.getLat()), Double.valueOf(pointDataListVO.getLng()));
                        //gpsDTO.setLongitude(new BigDecimal(coordinate[1]));
                        //gpsDTO.setLatitude(new BigDecimal(coordinate[0]));
                        gpsDTO.setLongitude(new BigDecimal(pointDataListVO.getLng()));
                        gpsDTO.setLatitude(new BigDecimal(pointDataListVO.getLat()));
                        gpsDTO.setTime(DateUtils.dateTimeToStringT(DateUtils.stringToDateTime(pointDataListVO.getReceiveTime())));
                        gpsDTOS.add(gpsDTO);
                    }
                    n++;
                }
            }

        }
        return gpsDTOS;
    }


    /**
     * 补传装货照片
     */
    public Result uploadShippingPickupImage(HyShippingNote hyShippingNote) {

        if (StrUtil.isEmpty(hyShippingNote.getLoadingSceneImg())) {
            return Result.error("该运单未找到装货现场照片");
        }

        String driverId = hyShippingNote.getDriverId();
        if (StrUtil.isEmpty(driverId)) {
            return Result.error("该运单司机不存在");
        }

        HyDriver hyDriver = driverService.getById(driverId);
        if (null == hyDriver) {
            return Result.error("该司机数据不存在");
        }

        ShippingImageDTO shippingImageDTO = new ShippingImageDTO();
        shippingImageDTO.setShipmentCode(hyShippingNote.getShippingNoteNumber());
        shippingImageDTO.setImageType("pickup");
        shippingImageDTO.setDriverCode(hyDriver.getIdcard());

        //照片发送坐标
        if (null == hyShippingNote.getSendLongitude() || null == hyShippingNote.getSendLatitude()) {
            String sendLngLat = this.amapService.coordinate(hyShippingNote.getSendAddress());
            if (StrUtil.isEmpty(sendLngLat) || sendLngLat.split(",").length < 2) {
                throw new JeecgBootException("发货地址坐标转换失败，请确认发货地址");
            }
            double[] coordinate = LngLonUtil.gcj02_To_Bd09(Double.valueOf(sendLngLat.split(",")[1]), Double.valueOf(sendLngLat.split(",")[0]));
            shippingImageDTO.setBaiduLatitude(String.valueOf(coordinate[0]));
            shippingImageDTO.setBaiduLongitude(String.valueOf(coordinate[1]));
        } else {
            shippingImageDTO.setBaiduLongitude(hyShippingNote.getSendLongitude().toString());
            shippingImageDTO.setBaiduLatitude(hyShippingNote.getSendLatitude().toString());
        }

        shippingImageDTO.setImageTakenDate(DateUtils.dateTimeToStringT(hyShippingNote.getStatusDtLoading()));
        //组装图片数据
        String prefix = hyShippingNote.getLoadingSceneImg().substring(hyShippingNote.getLoadingSceneImg().lastIndexOf('.') + 1);
        String base64 = ImageUtil.imgageToBase64(uploadpath + "/" + hyShippingNote.getLoadingSceneImg(), prefix);
        shippingImageDTO.setFileExt(prefix);
        shippingImageDTO.setFileName("pickup_" + System.currentTimeMillis());
        shippingImageDTO.setFileData(base64);

        AlctApiBaseResDTO alctApiBaseResDTO = this.appAlct56Service.uploadShippingImage(shippingImageDTO);
        if (!"0".equals(alctApiBaseResDTO.getCode())) {
            return Result.error(alctApiBaseResDTO.getMessage());
        }

        return Result.OK("操作成功");
    }


    /**
     * 补传卸货照片
     */
    public Result uploadShippingUnloadImage(HyShippingNote hyShippingNote) {

        if (StrUtil.isEmpty(hyShippingNote.getLoadingSceneImg())) {
            return Result.error("该运单未找到装货现场照片");
        }

        String driverId = hyShippingNote.getDriverId();
        if (StrUtil.isEmpty(driverId)) {
            return Result.error("该运单司机不存在");
        }

        HyDriver hyDriver = driverService.getById(driverId);
        if (null == hyDriver) {
            return Result.error("该司机数据不存在");
        }

        ShippingImageDTO shippingImageDTO = new ShippingImageDTO();
        shippingImageDTO.setShipmentCode(hyShippingNote.getShippingNoteNumber());
        shippingImageDTO.setImageType("unload");
        shippingImageDTO.setDriverCode(hyDriver.getIdcard());

        //卸货照片坐标
        if (null == hyShippingNote.getReceiveLongitude() || null == hyShippingNote.getReceiveLatitude()) {
            String recvLngLat = this.amapService.coordinate(hyShippingNote.getReceiveAddress());
            if (StrUtil.isEmpty(recvLngLat) || recvLngLat.split(",").length < 2) {
                throw new JeecgBootException("收货地址坐标转换失败，请确认收货地址");
            }
            double[] coordinate = LngLonUtil.gcj02_To_Bd09(Double.valueOf(recvLngLat.split(",")[1]), Double.valueOf(recvLngLat.split(",")[0]));
            shippingImageDTO.setBaiduLatitude(String.valueOf(coordinate[0]));
            shippingImageDTO.setBaiduLongitude(String.valueOf(coordinate[1]));
        } else {
            shippingImageDTO.setBaiduLongitude(hyShippingNote.getReceiveLongitude().toString());
            shippingImageDTO.setBaiduLatitude(hyShippingNote.getReceiveLatitude().toString());
        }

        shippingImageDTO.setImageTakenDate(DateUtils.dateTimeToStringT(hyShippingNote.getStatusDtUnloading()));
        //组装图片数据
        String prefix = hyShippingNote.getUnloadingSceneImg().substring(hyShippingNote.getUnloadingSceneImg().lastIndexOf('.') + 1);
        String base64 = ImageUtil.imgageToBase64(uploadpath + "/" + hyShippingNote.getUnloadingSceneImg(), prefix);
        shippingImageDTO.setFileExt(prefix);
        shippingImageDTO.setFileName("unload_" + System.currentTimeMillis());
        shippingImageDTO.setFileData(base64);

        AlctApiBaseResDTO alctApiBaseResDTO = this.appAlct56Service.uploadShippingImage(shippingImageDTO);
        if (!"0".equals(alctApiBaseResDTO.getCode())) {
            return Result.error(alctApiBaseResDTO.getMessage());
        }

        return Result.OK("操作成功");
    }


    public Result uploadShippingPodImage(HyShippingNote hyShippingNote) {

        if (StrUtil.isEmpty(hyShippingNote.getImgUnloading())) {
            return Result.error("该运单未找到卸货凭证");
        }

        ShippingImageDTO shippingImageDTO = new ShippingImageDTO();
        shippingImageDTO.setShipmentCode(hyShippingNote.getShippingNoteNumber());
        shippingImageDTO.setImageType("pod");

        //卸货照片坐标
//        if (null == hyShippingNote.getReceiveLongitude() || null == hyShippingNote.getReceiveLatitude()) {
//            String recvLngLat = this.amapService.coordinate(hyShippingNote.getReceiveAddress());
//            if (StrUtil.isEmpty(recvLngLat) || recvLngLat.split(",").length < 2) {
//                throw new JeecgBootException("收货地址坐标转换失败，请确认收货地址");
//            }
//            double[] coordinate = LngLonUtil.gcj02_To_Bd09(Double.valueOf(recvLngLat.split(",")[1]), Double.valueOf(recvLngLat.split(",")[0]));
//            shippingImageDTO.setBaiduLatitude(String.valueOf(coordinate[0]));
//            shippingImageDTO.setBaiduLongitude(String.valueOf(coordinate[1]));
//        } else {
//            shippingImageDTO.setBaiduLongitude(hyShippingNote.getReceiveLongitude().toString());
//            shippingImageDTO.setBaiduLatitude(hyShippingNote.getReceiveLatitude().toString());
//        }

        shippingImageDTO.setImageTakenDate(DateUtils.dateTimeToStringT(hyShippingNote.getStatusDtSign()));
        //组装图片数据
        String prefix = hyShippingNote.getImgUnloading().substring(hyShippingNote.getImgUnloading().lastIndexOf('.') + 1);
        String base64 = ImageUtil.imgageToBase64(uploadpath + "/" + hyShippingNote.getImgUnloading(), prefix);
        shippingImageDTO.setFileExt(prefix);
        shippingImageDTO.setFileName("pod_" + System.currentTimeMillis());
        shippingImageDTO.setFileData(base64);

        AlctApiBaseResDTO alctApiBaseResDTO = this.oapiAlct56Service.upImages(shippingImageDTO);
        if (!"0".equals(alctApiBaseResDTO.getCode())) {
            return Result.error(alctApiBaseResDTO.getMessage());
        }

        return Result.OK("操作成功");
    }




    /**
     * 获取频次
     *
     * @param a
     * @return
     */
    private int getFrequency(Integer a) {
        int b = 1;
        if (a > 1000 && a <= 2000) {
            b = 10;
        } else if (a > 2000 && a <= 3000) {
            b = 20;
        } else if (a > 3000 && a <= 4000) {
            b = 30;
        } else if (a > 4000 && a <= 5000) {
            b = 40;
        } else if (a > 5000 && a <= 6000) {
            b = 50;
        } else {
            b = 60;
        }
        return b;
    }

    /**
     * 陆交开放平台 保存运单状态
     *
     * @param hyShippingNote
     * @return
     */
    public Result saveAlctShippingNoteStatus(HyShippingNote hyShippingNote) {

        log.info("税务上报状态更新, {} {}", hyShippingNote.getShippingNoteNumber(), hyShippingNote.getAlctStatus());
        if (StrUtil.isEmpty(hyShippingNote.getShippingNoteNumber())
                || StrUtil.isEmpty(hyShippingNote.getAlctStatus())) {
            return Result.error("运单号或税务上报状态不能为空");
        }

        boolean bUpdate = this.hyShippingNoteService.update(new LambdaUpdateWrapper<HyShippingNote>()
                .eq(HyShippingNote::getShippingNoteNumber, hyShippingNote.getShippingNoteNumber())
                .set(HyShippingNote::getAlctStatus, hyShippingNote.getAlctStatus())
        );
        if (!bUpdate) {
            return Result.error("税务上报状态更新失败");
        }

        return Result.OK("状态更新成功");
    }


    /**
     * 陆交开放平台 司机获取运单状态
     *
     * @param hyShippingNote
     * @return
     */
    public Result getAlctShippingNoteByDriver(HyShippingNote hyShippingNote) {

        AlctApiBaseResDTO result = oapiAlct56Service.getAlctShippingNote(hyShippingNote.getShippingNoteNumber());
        if (result.getCode().equals("0")) {
            log.info("辽宁税务运单状态，司机 -> {}", JSONUtil.toJsonStr(result.getShipment()));

            JSONObject jsonObject = JSONUtil.parseObj(result.getShipment());
            if (StrUtil.isEmpty(jsonObject.getStr("status"))) {
                return Result.error("查询税务运单信息失败");
            }

            //只有是确认货源和已提货的状态下，司机才能看得见，当司机调用到货接口后就流转到了货主端
            if (jsonObject.getStr("status").equals("已确认")
                    || jsonObject.getStr("status").equals("已提货")) {

                HyShippingNote shippingNote = this.hyShippingNoteService.getByShippingNoteNumer(hyShippingNote.getShippingNoteNumber());
                if (null == shippingNote) {
                    return Result.error("平台中该运单不存在," + hyShippingNote.getShippingNoteNumber());
                }

                AlctShippingNoteVO vo = AlctShippingNoteVO.builder()
                        .shipmentCode(jsonObject.getStr("shipmentCode"))
                        .shippingNoteNumber(jsonObject.getStr("shippingNoteNumber"))
                        .status(jsonObject.getStr("status"))
                        .vehicleNumber(jsonObject.getStr("vehicleNumber"))
                        .statusCode(jsonObject.getInt("statusCode"))
                        .driverIdentification(jsonObject.getStr("driverIdentification"))
                        .sendAddress(shippingNote.getSendAddress())
                        .sendContactName(shippingNote.getSendContactName())
                        .sendContactTel(shippingNote.getSendContactTel())
                        .receiveAddress(shippingNote.getReceiveAddress())
                        .receiveContact(shippingNote.getReceiveContactName())
                        .receiveContactTel(shippingNote.getReceiveContactTel())
                        .build();

                return Result.OK(vo);
            } else {
                return Result.error("运单" + hyShippingNote.getShippingNoteNumber()
                        + "，当前状态已经是[" + jsonObject.getStr("status") + "],不需要进行操作");
            }
        }

        return Result.error(result.getMessage());
    }


    /**
     * 陆交开放平台 货主获取运单状态
     *
     * @param hyShippingNote
     * @return
     */
    public Result getAlctShippingNoteByCustomer(HyShippingNote hyShippingNote) {

        AlctApiBaseResDTO result = oapiAlct56Service.getAlctShippingNote(hyShippingNote.getShippingNoteNumber());
        if (result.getCode().equals("0")) {
            log.info("辽宁税务运单状态,货主 -> {}", JSONUtil.toJsonStr(result.getShipment()));

            JSONObject jsonObject = JSONUtil.parseObj(result.getShipment());
            if (StrUtil.isEmpty(jsonObject.getStr("status"))) {
                return Result.error("查询税务运单信息失败");
            }

            //只有是已到货、已签收和已结算的状态下，货主才看得到
//            if (jsonObject.getStr("status").equals("已卸货")
//             || jsonObject.getStr("status").equals("已签收")
//             || jsonObject.getStr("status").equals("已结算")) {

            HyShippingNote shippingNote = this.hyShippingNoteService.getByShippingNoteNumer(hyShippingNote.getShippingNoteNumber());
            if (null == shippingNote) {
                return Result.error("平台中该运单不存在," + hyShippingNote.getShippingNoteNumber());
            }

            HyOrder hyOrder = this.orderService.getById(shippingNote.getOrderId());
            if (null == hyOrder) {
                return Result.error("平台中运单所对应的货源不存在," + hyShippingNote.getShippingNoteNumber());
            }

            //取后8位数字当作货物itemNo
            String itemNumber = hyOrder.getOrderNum().substring(hyOrder.getOrderNum().length() - 8);
            HyDriver hyDriver = this.driverService.getDriverById(shippingNote.getDriverId());

            AlctShippingNoteVO vo = AlctShippingNoteVO.builder()
                    .shipmentCode(jsonObject.getStr("shipmentCode"))
                    .shippingNoteNumber(jsonObject.getStr("shippingNoteNumber"))
                    .status(jsonObject.getStr("status"))
                    .vehicleNumber(jsonObject.getStr("vehicleNumber"))
                    .statusCode(jsonObject.getInt("statusCode"))
                    .driverName(hyDriver.getDriverName())
                    .driverIdentification(jsonObject.getStr("driverIdentification"))
                    .sendAddress(shippingNote.getSendAddress())
                    .sendContactName(shippingNote.getSendContactName())
                    .sendContactTel(shippingNote.getSendContactTel())
                    .receiveAddress(shippingNote.getReceiveAddress())
                    .receiveContact(shippingNote.getReceiveContactName())
                    .receiveContactTel(shippingNote.getReceiveContactTel())
                    .itemNo(itemNumber)
                    .goodsName(hyOrder.getDescriptionOfGoods())
                    .quantity(shippingNote.getGoodsWeightLoading().toString())
                    .receiveQuantity(shippingNote.getGoodsWeightUnloading().toString())
                    .damageQuantity("0")
                    .lostQuantity(ObjectUtil.isEmpty(shippingNote.getGoodsWeightLoss()) ? "0": shippingNote.getGoodsWeightLoss().toString())
                    .unit(shippingNote.getGoodsUnit())
                    .build();

            return Result.OK(vo);
//            } else {
//                return Result.error("运单" + hyShippingNote.getShippingNoteNumber()
//                        + "，当前状态已经是[" + jsonObject.getStr("status") + "],不需要进行操作");
//            }
        }

        return Result.error(result.getMessage());
    }
}
